home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
422_02
/
misc
/
kidsmenu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-20
|
6KB
|
269 lines
/*
* KIDS MENU
*
* Copyright 1993-1994 Dave Dunfield
*
* Permission granted for personal (non-commercial) use only.
*
* Compile command: cc kmedit -fop
*/
#include <stdio.h>
#include <window.h>
#define MAXPACK 27
/* Termination codes */
#define BATCH 50
#define EXIT 51
#define BADARG 52
/* Mouse buttons */
#define MOUSE_LEFT 0x01 /* Select button */
#define MOUSE_RIGHT 0x02 /* Cancel button */
#define MOUSE_CENTER 0x04 /* Not used in MICROCAD */
int mousex = 0, mousey = 0, max_icon;
char cursor_flag = 0, video_mode = 3, mouse_flag = -1, quit_flag = -1,
*ifile = 0, *ofile = 0;
unsigned char itext[MAXPACK][8][6], iattr[MAXPACK][8][6],
idir[MAXPACK][50], icmd[MAXPACK][50];
char htext[] = {
"KIDS MENU - Copyright 1993-1994 Dave Dunfield, Freely Distributable.\n\n\
Use: KIDSMENU [B=batch_file D=data_file -Lock -Mouse V=video_mode]\n\n\
for Bethany and Michael.\n" };
/*
* Main program - process commands at the highest level
*/
main(argc, argv)
int argc;
char *argv[];
{
unsigned i, x, y, inkey;
char *ptr;
FILE *fp;
for(i=1; i < argc; ++i) {
ptr = argv[i];
switch((toupper(*ptr++) << 8) | toupper(*ptr++)) {
default:
printf("Invalid argument: %s\n\n", argv[i]);
case '?'<<8 :
case '/?' :
case '-?' :
fputs(htext, stdout);
exit(BADARG);
case 'V=' :
video_mode = atoi(ptr);
break;
case 'D=' :
ifile = ptr;
break;
case '-M' :
mouse_flag = 0;
break;
case '-L' :
quit_flag = 0;
break;
case 'B=' :
get_name(icmd, ptr, ".BAT");
ofile = fopen(icmd, "wvq"); } }
get_name(icmd, ifile || "KIDSMENU", ".DAT");
fp = fopen(icmd, "rvqb");
max_icon = 0;
do {
i = fread(itext[max_icon], sizeof(itext[0]), fp);
i += fread(iattr[max_icon], sizeof(iattr[0]), fp);
i += fread(idir [max_icon], sizeof(idir [0]), fp);
i += fread(icmd [max_icon], sizeof(icmd [0]), fp);
++max_icon; }
while(i == (sizeof(itext[0])+sizeof(iattr[0])+sizeof(idir[0])+sizeof(icmd[0])));
--max_icon;
fclose(fp);
runmenu:
set_video_mode(video_mode);
wopen(0, 0, 80, 25, WCOPEN|WCCLOSE|NORMAL);
W_OPEN->WINpcurx = W_OPEN->WINpcury = inkey = 0;
if(mouse_flag = mouse_flag && init_mouse())
wcursor_block();
else
wcursor_off();
/* Draw the ICONs */
for(i=x=y=0; i < max_icon; ++i) {
draw_icon(x, y, itext[i], iattr[i]);
*W_OPEN = NORMAL;
wgotoxy(x+3, y+6);
wprintf("%2u", i+1);
if((x += 9) > 79) {
x = 0;
y += 8; } }
again:
while(!(mouse_status() & MOUSE_LEFT)) switch(i = wtstc()) {
case _CEN :
if(quit_flag) {
*W_OPEN = NORMAL;
wclose();
fputs(htext, stdout);
exit(EXIT); }
break;
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
inkey = ((inkey % 10)*10) + (i - '0');
goto xdraw;
case _KBS :
inkey /= 10;
xdraw:
if(inkey > max_icon) {
inkey = 0;
wputc(7); }
wgotoxy(76, 24);
wprintf(inkey ? "%-2u" : " ", inkey);
mousex = mousey = -1;
break;
case '\n' :
if(inkey) {
i = inkey - 1;
goto runpgm; } }
if(((mousey % 8) >= 6) || ((mousex % 9) == 8))
goto again;
if((i = ((mousey/8)*9) + mousex/9) >= max_icon)
goto again;
runpgm:
*W_OPEN = NORMAL;
wclose();
if(ofile) {
fprintf(ofile,"CD %s\n", idir[i]);
fprintf(ofile,"%s\n", icmd[i]);
fclose(ofile);
exit(BATCH); }
cd(idir[i]);
system(icmd[i]);
goto runmenu;
}
/*
* Display the ICON
*/
draw_icon(x, y, text, attr)
unsigned x, y;
unsigned char text[8][6], attr[8][6];
{
int x1, y1;
for(y1=0; y1 < 6; ++y1) {
wgotoxy(x, y+y1);
for(x1 = 0; x1 < 8; ++x1) {
*W_OPEN = attr[x1][y1];
wputc((unsigned)text[x1][y1] | 0x0100); } }
}
/*
* Get a filename with extension only if necessary
*/
get_name(dest, name, ext)
char *dest, *name, *ext;
{
char c, flag;
flag = -1;
while(*dest = c = *name++) {
++dest;
if(c == '.')
flag = 0; }
if(flag)
while(*dest++ = *ext++);
}
/*
* Initializes the mouse driver, returns with -1 if successful.
*/
init_mouse() asm
{
; Initialize & test for mouse
XOR AX,AX ; Init functions.
INT 33h ; Call mouse driver
AND AX,AX ; Mouse present
JZ initm1 ; No, skip it
; Set mouse limits (some drivers do not do it properly on reset)
XOR CX,CX ; Lower limit is zero
MOV DX,799 ; Upper horizontal limit
MOV AX,7 ; Set horizontal limit
INT 33h ; Call mouse driver
MOV DX,499 ; Upper vertical limit
MOV AX,8 ; Set vertical limit
INT 33h ; Call mouse driver
MOV AX,-1 ; Indicate mouse ok
initm1:
}
/*
* Update mouse position and on-screen cursor. If any button is
* activated, remove cursor, wait for button to be released, and
* report it.
*/
mouse_status()
{
int x, y, z;
if(!mouse_flag)
return 0;
/* Get mouse position and button status */
asm {
MOV AX,0003h ; Mouse status function
INT 33h ; Call mouse driver
MOV -2[BP],BX ; Save buttons
MOV -4[BP],DX ; Save Y position
MOV -6[BP],CX ; Save X position
}
x /= 10; /* Get new X */
y /= 20; /* Get new Y */
/* If cursor position changed, update cursor and display*/
if((x != mousex) || (y != mousey))
wgotoxy(mousex = x, mousey = y);
/* If any buttons are activated, wait for release, remove cursor */
if(z & (MOUSE_LEFT|MOUSE_RIGHT|MOUSE_CENTER)) asm
{
mloop1: MOV AX,0003h ; Mouse status function
INT 33h ; Call mouse driver
AND BL,07h ; Any buttons down?
JNZ mloop1 ; Wait till clear
}
/* Pass back button status to caller */
return z;
}
/*
* Set video mode
*/
set_video_mode(x) asm
{
MOV AL,4[BP] ; Get mode
XOR AH,AH ; Set mode fucntion
INT 10h ; Call BIOS
}